<template>
  <div class="app-container cam-page">
    <div class="cam-content">
      <section class="panel cam-banner">
        <div class="banner-text">
          <h2>建议收集</h2>
          <p>匿名听取师生建议，用温度和设计感守护校园日常。</p>
        </div>
        <div class="banner-side">
          <div class="banner-stat">
            <span class="stat-label">当前建议</span>
            <span class="stat-value">{{ total }}</span>
          </div>
          <el-button
            class="chart-cta-btn"
            type="primary"
            icon="el-icon-s-opportunity"
            @click="openAnalysisDialog"
          >AI智能分析</el-button>
          <span class="cta-tip">调用 Deepseek 模型，自动生成建议分析报告</span>
        </div>
      </section>

      <section class="panel search-panel" v-show="showSearch">
        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="auto" class="cam-form">
          <el-form-item label="建议标题" prop="title">
            <el-input
              v-model="queryParams.title"
              placeholder="请输入建议标题"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="联系方式" prop="contactInfo">
            <el-input
              v-model="queryParams.contactInfo"
              placeholder="请输入联系方式"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="所属校区/学院" prop="campus">
            <el-input
              v-model="queryParams.campus"
              placeholder="请输入所属校区或学院"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="满意度评分" prop="satisfyScore">
            <el-input
              v-model="queryParams.satisfyScore"
              placeholder="请输入满意度评分"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
      </section>

      <section class="panel toolbar-panel">
        <el-row :gutter="10" class="mb8 cam-toolbar">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd"
              v-hasPermi="['system:suggestionOfCam:add']"
            >新增</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="success"
              plain
              icon="el-icon-edit"
              size="mini"
              :disabled="single"
              @click="handleUpdate"
              v-hasPermi="['system:suggestionOfCam:edit']"
            >修改</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="danger"
              plain
              icon="el-icon-delete"
              size="mini"
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['system:suggestionOfCam:remove']"
            >删除</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="warning"
              plain
              icon="el-icon-download"
              size="mini"
              @click="handleExport"
              v-hasPermi="['system:suggestionOfCam:export']"
            >导出</el-button>
          </el-col>
          <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>
      </section>

      <section class="panel table-panel">
        <div class="table-shell">
          <el-table v-loading="loading" :data="suggestionOfCamList" @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column label="建议ID" align="center" prop="suggestionId" />
            <el-table-column label="建议标题" align="center" prop="title" />
            <el-table-column label="建议内容" align="center" prop="content" />
            <el-table-column label="联系方式" align="center" prop="contactInfo" />
            <el-table-column label="所属校区/学院" align="center" prop="campus" />
            <el-table-column label="满意度评分" align="center" prop="satisfyScore" />
            <el-table-column label="备注" align="center" prop="remark" />
            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
              <template slot-scope="scope">
                <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-edit"
                  @click="handleUpdate(scope.row)"
                  v-hasPermi="['system:suggestionOfCam:edit']"
                >修改</el-button>
                <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-delete"
                  @click="handleDelete(scope.row)"
                  v-hasPermi="['system:suggestionOfCam:remove']"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="pagination-wrap">
          <pagination
            v-show="total>0"
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getList"
          />
        </div>
      </section>
    </div>

    <el-dialog :title="title" :visible.sync="open" width="520px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="建议标题" prop="title">
          <el-input v-model="form.title" placeholder="请输入建议标题" />
        </el-form-item>
        <el-form-item label="建议内容" prop="content">
          <el-input v-model="form.content" placeholder="请输入建议内容" type="textarea" :rows="4" />
        </el-form-item>
        <el-form-item label="联系方式" prop="contactInfo">
          <el-input v-model="form.contactInfo" placeholder="请输入联系方式（选填）" />
        </el-form-item>
        <el-form-item label="所属校区/学院" prop="campus">
          <el-input v-model="form.campus" placeholder="请输入所属校区或学院" />
        </el-form-item>
        <el-form-item label="满意度评分" prop="satisfyScore">
          <el-input v-model="form.satisfyScore" placeholder="请输入满意度评分（1-5）" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <el-dialog
      title="建议AI智能分析"
      :visible.sync="analysisDialogVisible"
      width="640px"
      append-to-body
      @close="analysisOutput = ''"
    >
      <div class="ai-dialog">
        <div
          class="ai-output"
          v-loading="analysisLoading"
          element-loading-text="AI 正在分析，请稍候…"
        >
          <template v-if="analysisOutput">
            <pre class="ai-output__text">{{ analysisOutput }}</pre>
          </template>
          <div class="ai-empty" v-else>
            点击“一键分析”即可基于最近的建议内容和满意度自动生成管理分析文案。
          </div>
        </div>

        <el-collapse v-model="analysisAdvanced" class="analysis-advanced">
          <el-collapse-item title="高级" name="advanced">
            <el-form label-width="120px" size="small" class="analysis-form">
              <el-form-item label="Deepseek API Key">
                <el-input
                  v-model="analysisForm.apiKey"
                  placeholder="请输入密钥（不会被存储）"
                  show-password
                />
              </el-form-item>
              <el-form-item label="模型">
                <el-select v-model="analysisForm.model" placeholder="请选择模型" style="width: 100%;">
                  <el-option
                    v-for="item in analysisModels"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="分析建议数量">
                <el-input-number
                  v-model="analysisForm.maxRecords"
                  :min="5"
                  :max="100"
                />
              </el-form-item>
              <el-form-item label="自定义提示">
                <el-input
                  v-model="analysisForm.prompt"
                  type="textarea"
                  :rows="2"
                  placeholder="例如：重点关注安全隐患或满意度较低的建议"
                />
              </el-form-item>
            </el-form>
          </el-collapse-item>
        </el-collapse>

        <div class="ai-actions">
          <el-button type="primary" icon="el-icon-lightning" @click="handleAnalysis">一键分析</el-button>
          <el-button
            icon="el-icon-download"
            :loading="analysisDownloading"
            :disabled="!analysisOutput || analysisDownloading"
            @click="downloadAnalysis"
          >导出文案</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listSuggestionOfCam, getSuggestionOfCam, delSuggestionOfCam, addSuggestionOfCam, updateSuggestionOfCam, analyzeSuggestionOfCam, exportSuggestionAnalysisDoc } from "@/api/system/suggestionOfCam"

export default {
  name: "SuggestionOfCam",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 是否仅单选
      single: true,
      // 是否多选
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 建议收集表格数据
      suggestionOfCamList: [],
      // 弹窗标题
      title: "",
      // 是否显示弹窗
      open: false,
      // AI 分析弹窗
      analysisDialogVisible: false,
      analysisLoading: false,
      analysisDownloading: false,
      analysisOutput: "",
      analysisAdvanced: [],
      analysisForm: {
        apiKey: "",
        model: "deepseek-chat",
        maxRecords: 20,
        prompt: "",
        temperature: 0.3
      },
      analysisModels: [
        { label: "Deepseek Chat", value: "deepseek-chat" },
        { label: "Deepseek Reasoner", value: "deepseek-reasoner" }
      ],
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        title: null,
        content: null,
        contactInfo: null,
        campus: null,
        satisfyScore: null
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        title: [
          { required: true, message: "建议标题不能为空", trigger: "blur" }
        ],
        content: [
          { required: true, message: "建议内容不能为空", trigger: "blur" }
        ]
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    /** 查询建议收集列表 */
    getList() {
      this.loading = true
      listSuggestionOfCam(this.queryParams).then(response => {
        this.suggestionOfCamList = response.rows
        this.total = response.total
        this.loading = false
      })
    },
    // 取消按钮
    cancel() {
      this.open = false
      this.reset()
    },
    // 表单重置
    reset() {
      this.form = {
        suggestionId: null,
        title: null,
        content: null,
        contactInfo: null,
        campus: null,
        satisfyScore: null,
        createTime: null,
        remark: null
      }
      this.resetForm("form")
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm")
      this.handleQuery()
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.suggestionId)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset()
      this.open = true
      this.title = "添加建议"
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset()
      const suggestionId = row.suggestionId || this.ids
      getSuggestionOfCam(suggestionId).then(response => {
        this.form = response.data
        this.open = true
        this.title = "修改建议"
      })
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.suggestionId != null) {
            updateSuggestionOfCam(this.form).then(() => {
              this.$modal.msgSuccess("修改成功")
              this.open = false
              this.getList()
            })
          } else {
            addSuggestionOfCam(this.form).then(() => {
              this.$modal.msgSuccess("新增成功")
              this.open = false
              this.getList()
            })
          }
        }
      })
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const suggestionIds = row.suggestionId || this.ids
      this.$modal.confirm('是否确认删除建议编号为"' + suggestionIds + '"的数据项？').then(() => {
        return delSuggestionOfCam(suggestionIds)
      }).then(() => {
        this.getList()
        this.$modal.msgSuccess("删除成功")
      }).catch(() => {})
    },
    openAnalysisDialog() {
      this.analysisDialogVisible = true
      this.analysisOutput = ""
    },
    handleAnalysis() {
      if (!this.analysisForm.apiKey) {
        this.$message.warning("请先在高级设置中填写 Deepseek API Key")
        return
      }
      const payload = {
        apiKey: this.analysisForm.apiKey,
        model: this.analysisForm.model,
        maxRecords: this.analysisForm.maxRecords,
        prompt: this.analysisForm.prompt,
        temperature: this.analysisForm.temperature
      }
      this.analysisLoading = true
      analyzeSuggestionOfCam(payload).then(response => {
        this.analysisOutput = response.data
        if (!this.analysisOutput) {
          this.analysisOutput = "AI 已完成分析，但未返回内容。"
        }
      }).catch(() => {
        this.$message.error("AI 分析失败，请检查密钥或网络设置")
        this.analysisOutput = ""
      }).finally(() => {
        this.analysisLoading = false
      })
    },
    downloadAnalysis() {
      if (!this.analysisOutput) {
        this.$message.warning("暂无可导出的文案")
        return
      }
      this.analysisDownloading = true
      const payload = { content: this.analysisOutput }
      exportSuggestionAnalysisDoc(payload).then(response => {
        if (!response) {
          this.$message.error("导出失败，请稍后重试")
          return
        }
        if (response.type && response.type.includes("application/json")) {
          const reader = new FileReader()
          reader.onload = e => {
            try {
              const result = JSON.parse(e.target.result || "{}")
              this.$message.error(result.msg || "导出失败，请稍后重试")
            } catch (_) {
              this.$message.error("导出失败，请稍后重试")
            }
          }
          reader.readAsText(response)
          return
        }
        const blob = new Blob([response], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" })
        const url = window.URL.createObjectURL(blob)
        const link = document.createElement("a")
        link.href = url
        link.download = `suggestion-analysis-${Date.now()}.docx`
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        window.URL.revokeObjectURL(url)
      }).catch(() => {
        this.$message.error("导出失败，请检查网络或稍后再试")
      }).finally(() => {
        this.analysisDownloading = false
      })
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('system/suggestionOfCam/export', {
        ...this.queryParams
      }, `suggestionOfCam_${new Date().getTime()}.xlsx`)
    }
  }
}
</script>

<style lang="scss" scoped>
.cam-page {
  background: linear-gradient(130deg, #eef2ff 0%, #fbf0ff 45%, #ebf9ff 100%);
  min-height: calc(100vh - 86px);
  padding: 24px;
}

.cam-content {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.panel {
  --panel-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(253, 252, 255, 0.92));
  position: relative;
  background:
    var(--panel-bg) padding-box,
    linear-gradient(120deg, rgba(95, 137, 255, 0.35), rgba(241, 148, 255, 0.32), rgba(189, 228, 255, 0.4)) border-box;
  border-radius: 18px;
  border: 4px solid transparent;
  box-shadow: 0 30px 65px -45px rgba(21, 32, 67, 0.9);
  padding: 20px 24px;
  backdrop-filter: blur(8px);
  z-index: 0;
}

.cam-banner {
  --panel-bg: linear-gradient(120deg, rgba(85, 110, 255, 0.18), rgba(234, 86, 255, 0.14));
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.banner-text h2 {
  margin: 0 0 6px;
  font-size: 22px;
  color: #2b2d42;
  font-weight: 600;
}

.banner-text p {
  margin: 0;
  color: #5b6180;
  font-size: 14px;
}

.banner-stat {
  text-align: right;
  color: #252846;
}

.banner-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  min-width: 260px;
}

.chart-cta-btn {
  border: none;
  padding: 12px 28px;
  font-size: 15px;
  border-radius: 999px;
  background: linear-gradient(120deg, #546dff, #8881ff, #ff72c0);
  color: #fff;
  box-shadow: 0 18px 35px -18px rgba(84, 109, 255, 0.9), 0 10px 25px -18px rgba(255, 114, 192, 0.9);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  animation: chartPulse 2.6s ease-in-out infinite;
}

.chart-cta-btn .el-icon-s-opportunity {
  margin-right: 6px;
}

.chart-cta-btn:hover {
  transform: translateY(-2px) scale(1.02);
  box-shadow: 0 28px 45px -18px rgba(84, 109, 255, 0.85), 0 12px 32px -18px rgba(255, 114, 192, 0.85);
}

.cta-tip {
  font-size: 12px;
  color: #5b6180;
}

@keyframes chartPulse {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 114, 192, 0.3);
  }
  70% {
    box-shadow: 0 0 0 14px rgba(255, 114, 192, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 114, 192, 0);
  }
}

.stat-label {
  font-size: 13px;
  display: block;
  margin-bottom: 4px;
  opacity: 0.8;
}

.stat-value {
  font-size: 34px;
  line-height: 1;
  font-weight: 600;
}

.search-panel {
  padding-bottom: 6px;
}

.cam-form {
  width: 100%;
}

.search-panel ::v-deep .el-form-item {
  margin-right: 12px;
  margin-bottom: 16px;
}

.search-panel ::v-deep .el-input__inner {
  border-radius: 10px;
  background: #f5f7ff;
  border-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(91, 105, 207, 0.08);
}

.search-panel ::v-deep .el-input__inner:focus {
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.35);
}

.toolbar-panel {
  padding: 14px 24px 10px;
}

.cam-toolbar {
  width: 100%;
}

.toolbar-panel ::v-deep .el-row {
  align-items: center;
  flex-wrap: wrap;
  row-gap: 8px;
}

.toolbar-panel ::v-deep .el-col {
  min-width: 120px;
}

.toolbar-panel ::v-deep .el-button {
  border-radius: 999px;
  padding: 0 18px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.toolbar-panel ::v-deep .el-button:hover {
  transform: translateY(-1px);
}

.table-panel {
  padding: 18px 24px 8px;
}

.table-shell {
  border-radius: 18px;
  overflow: hidden;
  border: 4px solid transparent;
  background:
    linear-gradient(180deg, #ffffff, #fdfdff) padding-box,
    linear-gradient(120deg, rgba(93, 144, 255, 0.35), rgba(179, 231, 255, 0.4)) border-box;
  box-shadow: 0 35px 65px -45px rgba(0, 16, 54, 0.9);
}

.table-panel ::v-deep .el-table {
  background-color: white;
}

.table-panel ::v-deep .el-table__header-wrapper th {
  background: linear-gradient(90deg, #f9faff 0%, #f0f4ff 100%);
  color: #475467;
  font-weight: 600;
}

.table-panel ::v-deep .el-table__body tr {
  transition: background 0.2s ease;
}

.table-panel ::v-deep .el-table__body tr:hover > td {
  background: rgba(98, 117, 255, 0.08);
}

.table-panel ::v-deep .el-table .cell {
  color: #2f3142;
}

.pagination-wrap {
  display: flex;
  justify-content: flex-end;
  padding: 16px 4px 0;
}

.ai-dialog {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.ai-output {
  min-height: 220px;
  border-radius: 16px;
  border: 1px solid rgba(93, 144, 255, 0.25);
  background: rgba(255, 255, 255, 0.95);
  padding: 16px;
  font-size: 14px;
  color: #2f3142;
  position: relative;
}

.ai-output__text {
  white-space: pre-wrap;
  font-family: "SFMono-Regular", Consolas, "PingFang SC", sans-serif;
  line-height: 1.6;
}

.ai-empty {
  color: #8c8ea1;
}

.analysis-advanced {
  border: 1px dashed rgba(93, 144, 255, 0.35);
  border-radius: 12px;
  padding: 6px 10px;
}

.analysis-advanced ::v-deep .el-collapse-item__header {
  font-weight: 600;
}

.analysis-form {
  padding-top: 8px;
}

.ai-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

@media (max-width: 1180px) {
  .cam-content {
    max-width: 100%;
  }

  .banner-stat {
    text-align: left;
  }

  .banner-side {
    align-items: flex-start;
  }
}

@media (max-width: 768px) {
  .cam-page {
    padding: 16px;
  }

  .cam-banner {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .banner-side {
    width: 100%;
  }

  .toolbar-panel ::v-deep .el-col {
    min-width: 140px;
  }
}
</style>
